﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;

namespace Common
{
    public class Utils
    {
        #region 日期函数
        /// <summary>
                /// 取得某月的第一天
                /// </summary>
                /// <param name="datetime">要取得月份第一天的时间</param>
                /// <returns></returns>
        public static DateTime FirstDayOfMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day);
        }

        //// <summary>
        /// 取得某月的最后一天
        /// </summary>
        /// <param name="datetime">要取得月份最后一天的时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1);
        }

        //// <summary>
        /// 取得上个月第一天
        /// </summary>
        /// <param name="datetime">要取得上个月第一天的当前时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfPreviousMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddMonths(-1);
        }

        //// <summary>
        /// 取得上个月的最后一天
                 /// </summary>
                /// <param name="datetime">要取得上个月最后一天的当前时间</param>
                /// <returns></returns>
        public static DateTime LastDayOfPrdviousMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddDays(-1);
        }
        #endregion 日期函数
        #region 中文字串处理函数
        /// 判断句子中是否含有中文
        /// </summary>
        /// <param >字符串</param>
        public static bool ContainChineseCharacter(string words)
        {
           
            return  Regex.IsMatch(words, "[\u4e00-\u9fa5]{0,}"); ;
        }
        public static bool IsChn(char c)
        {
            return c >= 0x4e00 && c < 0x9fbb;
        }
        public static bool IsChn(string ch)
        {
            return ch[0] >= 0x4e00 && ch[0] < 0x9fbb;
        }
        /// <summary>
        /// 以遇到的第一个中文字符划分子串
        /// </summary>
        /// <param name="source"></param>
        /// <returns>第一个字串为第一个中文字符前的字符串，第二个字串为剩余的字串</returns>
        public static string[] SplitByChn(string source)
        {

            string[] subStrs = new string[2];
            int i = 0;
            for (i = 0; i < source.Length; i++)
            {
                if (IsChn(source[i])) break;
                else subStrs[0] += source[i];
            }
            subStrs[1] = source.Substring(i + 1);
            return subStrs;
        }
        /// <summary>
        /// 整数变换成中文习惯格式，如10086变换成一万〇八十六
        /// 支持到万，可选以年号返回，如2008->二〇〇八
        /// </summary>
        /// <param name="number"></param>
        /// <param name="yearNumFormat">是否以年号格式返回</param>
        /// <returns></returns>
        public static string Int2Chinese(int number,bool yearNumFormat=false)
        {//1.将数字字符变换成中文字符 2.插入“十”、“百”、“千”... 3.删除“〇万”的万“〇千”的千....4.如果有连续多个“〇”，就去掉重复的“〇”
            char[] chnNumbers = new char[] { '〇', '一', '二', '三', '四', '五', '六', '七', '八', '九' };
            //将数字转成字符串 
            List<char> numCharsChn = new List<char>();//
            string numstr = number.ToString();
            for (int i = 0; i < numstr.Length; i++)
            {
                int n = Convert.ToInt16(numstr.Substring(i, 1));
                numCharsChn.Add(chnNumbers[n]);
            }
           if(yearNumFormat)
            {//以年号格式返回
                return new string(numCharsChn.ToArray());
            }
            //插入“十”、“百”、“千”..
            if (numstr.Length>1) //插入“十”
            {
                numCharsChn.Insert(numCharsChn.Count - 1, '十');//54321->五四三二十一
            }
            if (numstr.Length > 2) //插入“百”
            {
                numCharsChn.Insert(numCharsChn.Count - 3, '百');//321->五四三百二十一
            }
            if (numstr.Length > 3) //插入“千”
            {
                numCharsChn.Insert(numCharsChn.Count - 5, '千');//4321->五四千三百二十一
            }
            if (numstr.Length > 4) //插入“万”
            {
                numCharsChn.Insert(numCharsChn.Count - 7, '万');//54321->五万四千三百二十一
            }

            //删除“〇万”的万“〇千”的千....
            string cnStr = new string(numCharsChn.ToArray());
            cnStr = Regex.Replace(cnStr, "〇[万千百十]", "〇");
            cnStr = Regex.Replace(cnStr, "〇{1,}", "〇");
            if(cnStr.StartsWith("一十"))
            {
                cnStr = cnStr.Substring(1);
            }
            return cnStr.TrimEnd('〇'); 
        }
        /// <summary>
        /// 统计字符c在字符串source中出现的次数
        /// </summary>
        /// <param name="source"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        public static int CountChar(string source, char c)
        {
            int n = 0;
            foreach (char ch in source)
            {
                if (ch == c) n++;
            }
            return n;
        }
        /// <summary>
        /// 返回一个元素在数组中的位置
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array"></param>
        /// <param name="matchingValue"></param>
        /// <returns></returns>
        public static int Indexof<T>(T[] array, T matchingValue)
        {
            int ind = -1;
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i].Equals(matchingValue))
                {
                    ind = i;
                    break;
                }
            }
            return ind;
        }

        #endregion
      
        /// <summary>
        /// 判断两个数组是否完全相等
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="arrayA"></param>
        /// <param name="arrayB"></param>
        /// <returns></returns>
        public static bool IsEqualArray<T>(T[] arrayA, T[] arrayB)
        {
            if (arrayA == null || arrayB == null) return false;
            else if (arrayA.Length != arrayB.Length) return false;
            for (int i = 0; i < arrayA.Length; i++)
            {
                if (!Equals(arrayA[i], arrayB[i]))
                {
                    return false;
                }
            }
            return true;
        }

        #region Functions From Liang
        public static void DataTableToXml(System.Data.DataTable table, string path)
        {
            StreamWriter sw = new StreamWriter(path, false);
            sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            sw.WriteLine("<DataTable>");
            // 列数据
            sw.WriteLine("\t<Columns>");
            for (int i = 0; i < table.Columns.Count; ++i)
                sw.WriteLine("\t\t<Column name = \"" + table.Columns[i].ColumnName + "\"/>");
            sw.WriteLine("\t</Columns>");
            // 行数据
            for (int i = 0; i < table.Rows.Count; ++i)
            {
                sw.WriteLine("\t<Row>");
                for (int j = 0; j < table.Columns.Count; ++j)
                    sw.WriteLine("\t\t<" + table.Columns[j].ColumnName + ">"
                        + table.Rows[i][j].ToString()
                        + "</" + table.Columns[j].ColumnName + ">");
                sw.WriteLine("\t</Row>");
            }
            sw.WriteLine("</DataTable>");
            sw.Close();
        }

        public static bool XmlToDataTable(string path, ref System.Data.DataTable table)
        {

            FileInfo fi = new FileInfo(path);
            if (!fi.Exists)
            {
                throw (new Exception("Util.XmlToDataTable, 文件 '" + path + "' 不存在."));
            }

            table.Rows.Clear();

            XmlReader reader = new XmlTextReader(path);
            XmlDocument doc = new XmlDocument();
            doc.Load(reader);
            XmlNode root = doc.DocumentElement;
            XmlNodeList nodelist = root.SelectNodes("Columns/Column");
            if (NeedClearColumn(nodelist, table))
            {
                table.Rows.Clear();
                table.Columns.Clear();
                foreach (XmlNode node in nodelist)
                {
                    XmlNode columnNode = node.SelectSingleNode("@name");
                    if (columnNode == null)
                    {
                        reader.Close();
                        throw (new Exception("Util.XmlToDataTable, 读取文件 '" + path + "' 时找不到属性名name."));

                    }
                    table.Columns.Add(columnNode.InnerText);
                }
            }

            nodelist = root.SelectNodes("Row");
            foreach (XmlNode node in nodelist)
            {
                System.Data.DataRow newRow = table.NewRow();
                foreach (System.Data.DataColumn column in table.Columns)
                {
                    XmlNode dataNode = node.SelectSingleNode(column.ColumnName);
                    if (dataNode == null)
                    {
                        reader.Close();
                        throw (new Exception("Util.XmlToDataTable,读取文件 '" + path + "' 时找不到结点 '" + column.ColumnName + "'."));
                    }
                    newRow[column.ColumnName] = dataNode.InnerText;
                }
                table.Rows.Add(newRow);
            }
            reader.Close();
            return true;
        }
        private static bool NeedClearColumn(XmlNodeList nodelist, System.Data.DataTable table)
        {
            if (nodelist.Count != table.Columns.Count)
                return true;

            foreach (XmlNode node in nodelist)
            {
                XmlNode columnNode = node.SelectSingleNode("@name");
                if (columnNode == null)
                    return true;
                if (!table.Columns.Contains(columnNode.InnerText))
                    return true;
            }

            return false;
        }

        #endregion Functions From Liang
    }
}
